prepare($sql); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("Get classes error: " . $e->getMessage()); return []; } } function getAcademicYears() { global $DBcon; try { $sql = "SELECT academic_year FROM calender ORDER BY academic_year DESC"; $stmt = $DBcon->prepare($sql); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("Get academic years error: " . $e->getMessage()); return []; } } // NEW FUNCTION: Insert record into promoted table function insertIntoPromotedTable($regno, $academic_year, $class_id) { global $DBcon; try { $sql = "INSERT INTO promoted (regno, accademic_year, class_id) VALUES (:regno, :accademic_year, :class_id)"; $stmt = $DBcon->prepare($sql); $result = $stmt->execute([ ':regno' => sanitize_input($regno), ':accademic_year' => sanitize_input($academic_year), ':class_id' => sanitize_input($class_id) ]); return $result; } catch (PDOException $e) { error_log("Insert into promoted table error: " . $e->getMessage()); return false; } } // NEW FUNCTION: Update record in promoted table function updatePromotedTable($old_regno, $new_regno, $academic_year, $class_id) { global $DBcon; try { // First check if record exists in promoted table $check_sql = "SELECT sn FROM promoted WHERE regno = :old_regno"; $check_stmt = $DBcon->prepare($check_sql); $check_stmt->execute([':old_regno' => sanitize_input($old_regno)]); $existing_record = $check_stmt->fetch(PDO::FETCH_ASSOC); if ($existing_record) { // Update existing record $sql = "UPDATE promoted SET regno = :new_regno, accademic_year = :accademic_year, class_id = :class_id WHERE regno = :old_regno"; $stmt = $DBcon->prepare($sql); $result = $stmt->execute([ ':new_regno' => sanitize_input($new_regno), ':accademic_year' => sanitize_input($academic_year), ':class_id' => sanitize_input($class_id), ':old_regno' => sanitize_input($old_regno) ]); } else { // Insert new record if not exists $result = insertIntoPromotedTable($new_regno, $academic_year, $class_id); } return $result; } catch (PDOException $e) { error_log("Update promoted table error: " . $e->getMessage()); return false; } } // NEW FUNCTION: Delete record from promoted table function deleteFromPromotedTable($regno) { global $DBcon; try { $sql = "DELETE FROM promoted WHERE regno = :regno"; $stmt = $DBcon->prepare($sql); return $stmt->execute([':regno' => sanitize_input($regno)]); } catch (PDOException $e) { error_log("Delete from promoted table error: " . $e->getMessage()); return false; } } // CRUD Functions function getAllStudents($filters = [], $page = 1, $per_page = 25) { global $DBcon; try { // Build WHERE clause based on filters $where_clause = ""; $params = []; if (!empty($filters['class_id'])) { $where_clause .= " WHERE class_id = :class_id"; $params[':class_id'] = $filters['class_id']; } if (!empty($filters['admin_year'])) { $where_clause .= empty($where_clause) ? " WHERE" : " AND"; $where_clause .= " admin_year = :admin_year"; $params[':admin_year'] = $filters['admin_year']; } // Get total count for pagination $count_sql = "SELECT COUNT(*) as total FROM students_info" . $where_clause; $count_stmt = $DBcon->prepare($count_sql); $count_stmt->execute($params); $total_result = $count_stmt->fetch(PDO::FETCH_ASSOC); $total_records = $total_result['total']; $total_pages = ceil($total_records / $per_page); // Calculate offset $offset = ($page - 1) * $per_page; // Get students with pagination $sql = "SELECT * FROM students_info" . $where_clause . " ORDER BY sn DESC LIMIT :offset, :per_page"; $stmt = $DBcon->prepare($sql); // Bind parameters foreach ($params as $key => $value) { $stmt->bindValue($key, $value); } $stmt->bindValue(':offset', $offset, PDO::PARAM_INT); $stmt->bindValue(':per_page', $per_page, PDO::PARAM_INT); $stmt->execute(); $students = $stmt->fetchAll(PDO::FETCH_ASSOC); return [ 'students' => $students, 'total_records' => $total_records, 'total_pages' => $total_pages, 'current_page' => $page ]; } catch (PDOException $e) { error_log("Get all students error: " . $e->getMessage()); return [ 'students' => [], 'total_records' => 0, 'total_pages' => 0, 'current_page' => 1 ]; } } function getStudent($id) { global $DBcon; try { $sql = "SELECT * FROM students_info WHERE sn = :id"; $stmt = $DBcon->prepare($sql); $stmt->execute([':id' => intval($id)]); $result = $stmt->fetch(PDO::FETCH_ASSOC); return $result; } catch (PDOException $e) { error_log("Get student error: " . $e->getMessage()); return false; } } function createStudent($data, $files) { global $DBcon; try { $image_path = handleImageUpload($files, $data); $sql = "INSERT INTO students_info (fullname, regno, class_id, admin_year, image) VALUES (:fullname, :regno, :class_id, :admin_year, :image)"; $stmt = $DBcon->prepare($sql); $result = $stmt->execute([ ':fullname' => sanitize_input($data['fullname']), ':regno' => sanitize_input($data['regno']), ':class_id' => sanitize_input($data['class_id']), ':admin_year' => sanitize_input($data['admin_year']), ':image' => $image_path ]); // INSERT INTO PROMOTED TABLE - NEW CODE ADDED if ($result) { $promoted_result = insertIntoPromotedTable($data['regno'], $data['admin_year'], $data['class_id']); if (!$promoted_result) { error_log("Failed to insert into promoted table for student: " . $data['regno']); // Don't return false here as student creation was successful // Just log the error for the promoted table insertion } } return $result; } catch (PDOException $e) { error_log("Create student error: " . $e->getMessage()); return false; } } function updateStudent($data, $files) { global $DBcon; try { // Get current student data first $current_student = getStudent($data['id']); if (!$current_student) { return false; } // Handle image upload $image_path = handleImageUpload($files, $data); // If no new image was uploaded, keep the current image if ($image_path === '') { $image_path = $current_student['image']; } else if ($image_path !== false) { // New image was uploaded successfully, delete old image if it exists if (!empty($current_student['image']) && file_exists('../' . $current_student['image'])) { unlink('../' . $current_student['image']); } } else { // Image upload failed $image_path = $current_student['image']; } $sql = "UPDATE students_info SET fullname = :fullname, regno = :regno, class_id = :class_id, admin_year = :admin_year, image = :image WHERE sn = :id"; $stmt = $DBcon->prepare($sql); $params = [ ':fullname' => sanitize_input($data['fullname']), ':regno' => sanitize_input($data['regno']), ':class_id' => sanitize_input($data['class_id']), ':admin_year' => sanitize_input($data['admin_year']), ':image' => $image_path, ':id' => intval($data['id']) ]; $result = $stmt->execute($params); // UPDATE PROMOTED TABLE - NEW CODE ADDED if ($result) { $update_promoted = updatePromotedTable($current_student['regno'], $data['regno'], $data['admin_year'], $data['class_id']); if (!$update_promoted) { error_log("Failed to update promoted table for student: " . $data['regno']); // Don't return false here as student update was successful // Just log the error for the promoted table update } } return $result; } catch (PDOException $e) { error_log("Update student error: " . $e->getMessage()); return false; } } function handleImageUpload($files, $data) { // Check for webcam image first if (!empty($data['webcam_image']) && $data['webcam_image'] !== 'data:,') { return saveWebcamImage($data['webcam_image']); } // Check for file upload if (isset($files['image_upload']) && $files['image_upload']['error'] === UPLOAD_ERR_OK) { return saveUploadedImage($files['image_upload']); } // No image provided - return empty string return ''; } function saveWebcamImage($base64_image) { $upload_dir = '../uploads/students/'; // Create upload directory if it doesn't exist if (!file_exists($upload_dir)) { mkdir($upload_dir, 0755, true); } // Extract base64 data if (preg_match('/^data:image\/(\w+);base64,/', $base64_image, $type)) { $image_data = substr($base64_image, strpos($base64_image, ',') + 1); $type = strtolower($type[1]); // jpg, png, gif if (!in_array($type, ['jpg', 'jpeg', 'png', 'gif'])) { return false; } $image_data = base64_decode($image_data); if ($image_data === false) { return false; } } else { return false; } $filename = 'student_' . uniqid() . '.' . $type; $filepath = $upload_dir . $filename; if (file_put_contents($filepath, $image_data)) { return 'uploads/students/' . $filename; } return false; } function saveUploadedImage($file) { $upload_dir = '../uploads/students/'; $allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']; $max_size = 2 * 1024 * 1024; // 2MB // Create upload directory if it doesn't exist if (!file_exists($upload_dir)) { mkdir($upload_dir, 0755, true); } // Validate file if (!in_array($file['type'], $allowed_types)) { return false; } if ($file['size'] > $max_size) { return false; } // Generate unique filename $extension = pathinfo($file['name'], PATHINFO_EXTENSION); $filename = 'student_' . uniqid() . '.' . $extension; $filepath = $upload_dir . $filename; if (move_uploaded_file($file['tmp_name'], $filepath)) { return 'uploads/students/' . $filename; } return false; } function deleteStudent($id) { global $DBcon; try { // Get student data first to delete from promoted table $student = getStudent($id); if (!$student) { return false; } // DELETE FROM PROMOTED TABLE - NEW CODE ADDED if ($student && !empty($student['regno'])) { $delete_promoted = deleteFromPromotedTable($student['regno']); if (!$delete_promoted) { error_log("Failed to delete from promoted table for student: " . $student['regno']); // Continue with student deletion even if promoted table deletion fails } } // Delete student image if it exists if (!empty($student['image']) && file_exists('../' . $student['image'])) { unlink('../' . $student['image']); } $sql = "DELETE FROM students_info WHERE sn = :id"; $stmt = $DBcon->prepare($sql); return $stmt->execute([':id' => intval($id)]); } catch (PDOException $e) { error_log("Delete student error: " . $e->getMessage()); return false; } } // Generate CSRF token $csrf_token = generate_csrf_token(); // Get classes and academic years $classes = getClasses(); $academic_years = getAcademicYears(); // Initialize variables $action = isset($_GET['action']) ? sanitize_input($_GET['action']) : 'list'; $id = isset($_GET['id']) ? intval($_GET['id']) : 0; $message = ''; $message_type = ''; $student = null; // Handle form submissions if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Validate CSRF token if (!validate_csrf_token($_POST['csrf_token'])) { $message = 'Security token validation failed.'; $message_type = 'error'; } else { // Process different actions switch ($_POST['action']) { case 'create': $result = createStudent($_POST, $_FILES); if ($result) { $message = 'Student created successfully.'; $message_type = 'success'; $action = 'list'; } else { $message = 'Failed to create student. Please try again.'; $message_type = 'error'; } break; case 'update': $result = updateStudent($_POST, $_FILES); if ($result) { $message = 'Student updated successfully.'; $message_type = 'success'; $action = 'list'; } else { $message = 'Failed to update student. Please try again.'; $message_type = 'error'; } break; case 'delete': $result = deleteStudent($_POST['id']); if ($result) { $message = 'Student deleted successfully.'; $message_type = 'success'; } else { $message = 'Failed to delete student. Please try again.'; $message_type = 'error'; } break; case 'bulk_delete': if (isset($_POST['selected_students']) && is_array($_POST['selected_students'])) { $success_count = 0; $error_count = 0; foreach ($_POST['selected_students'] as $student_id) { if (deleteStudent($student_id)) { $success_count++; } else { $error_count++; } } if ($success_count > 0) { $message = "Successfully deleted $success_count student(s)."; $message_type = 'success'; if ($error_count > 0) { $message .= " Failed to delete $error_count student(s)."; } } else { $message = 'Failed to delete selected students.'; $message_type = 'error'; } } else { $message = 'No students selected for deletion.'; $message_type = 'error'; } break; } } } // If editing, get student data if ($action === 'edit') { $student = getStudent($id); if (!$student) { $message = 'Student not found.'; $message_type = 'error'; $action = 'list'; } } // Get filter parameters $filter_class = isset($_GET['filter_class']) ? sanitize_input($_GET['filter_class']) : ''; $filter_year = isset($_GET['filter_year']) ? sanitize_input($_GET['filter_year']) : ''; $current_page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1; // Build filters array $filters = []; if (!empty($filter_class)) { $filters['class_id'] = $filter_class; } if (!empty($filter_year)) { $filters['admin_year'] = $filter_year; } // Get students with filters and pagination $students_data = getAllStudents($filters, $current_page, 25); $students = $students_data['students']; $total_records = $students_data['total_records']; $total_pages = $students_data['total_pages']; ?> Student Management - School Admin
Clear
Showing of records
0): ?>
# Image Full Name Registration No Class Admission Year Actions
Student Image

No students found. Try changing your filters or clear all filters. Add the first student.

1): ?>
Upload File Take Photo Current Image
Max file size: 2MB. Allowed types: JPG, JPEG, PNG, GIF
Current Image

Current student image